
#ifndef __MY_DATA__
#define __MY_DATA__
#include "util.hpp"
#include <cstdlib>
#include <mutex>
#include <mysql/mysql.h>
using namespace aod;
namespace aod{
    #define  HOST "127.0.0.1"
    #define  USER "root"
    #define  PASS "123456"
    #define  NAME "aod_system"
    static MYSQL *MysqlInit()
    {
        MYSQL *mysql=mysql_init(NULL);
        if(mysql==NULL)
        {
            cout<<"init mysql failed"<<endl;
            return NULL;
        }
        if(mysql_real_connect(mysql,HOST,USER,PASS,NAME,0,NULL,0)==NULL){
         cout<<"connect mysql failed"<<endl;
         mysql_close(mysql);
         return NULL;
        }
        mysql_set_character_set(mysql,"utf8");
        return mysql;
    }
    static void MysqlDestory(MYSQL *mysql)
    {
        if(mysql!=NULL)
        {
        mysql_close(mysql);
        }
        return;
    }
    static bool MysqlQuery(MYSQL *mysql,const string &sql)
    {
        int ret=mysql_query(mysql,sql.c_str());
        if(ret!=0)
        {
            cout<<sql<<endl;
            cout<<mysql_error(mysql)<<endl;
            return false;
        }
        return true;
    }
    class TableVideo
    {
    private:
        MYSQL *_mysql; // 一个对象就是一个客户端，管理一张表
        mutex _mutex;  // 防止多个对象同时操作
    public:
        TableVideo()
        {
            _mysql=MysqlInit();
            if(_mysql==NULL)
            {
                exit(-1);
            }
        }
        ~TableVideo()
        {
            MysqlDestory(_mysql);
        }
        bool Insert(const Json::Value &video)                // 新增-传入视频信息
        {
            string sql;
            sql.resize(4090+video["info"].asString().size());
            #define INSERT_VIDEO "insert into tb_video values(null,'%s','%s','%s','%s');"
            sprintf(&sql[0],INSERT_VIDEO,video["name"].asString().c_str(),
                                         video["info"].asString().c_str(),
                                         video["video"].asString().c_str(),
                                         video["image"].asString().c_str());
             return MysqlQuery(_mysql,sql);
        }
        bool Update(int Video_id, const Json::Value &video)   // 修改视频信息
        {
            string sql;
            sql.resize(4090+video["info"].asString().size());
            // #define UPDATE_VIDEO "update tb_video set name='%s' info='%s' where id=%d;"
            #define UPDATE_VIDEO "update tb_video set name='%s', info='%s' where id=%d;"
            sprintf(&sql[0],UPDATE_VIDEO,video["name"].asString().c_str(),
                                         video["info"].asString().c_str(),
                                         Video_id);
            return MysqlQuery(_mysql,sql);
        }
        bool Delete(const int video_id)                        // 删除视频信息
        {
            #define DELETE_VIDEO "delete from tb_video where id=%d;"
            char sql[1024]={0};
            sprintf(sql,DELETE_VIDEO,video_id);
            return MysqlQuery(_mysql,sql); 
        }
        bool SelectAll(Json::Value *videos)                    // 查询所有视频信息
        {
            #define SELECTALL_VIDEO "select * from tb_video;"
            _mutex.lock();//加锁
            bool ret=MysqlQuery(_mysql,SELECTALL_VIDEO);
            if(ret==false)
            {
                 _mutex.unlock();
                return false;
            }
            MYSQL_RES *res=mysql_store_result(_mysql);
            if(res==NULL)
            {
                _mutex.unlock();
                cout<<"mysql store result fauiled"<<endl;
                return false;
            }
            int num_row=mysql_num_rows(res);
            for(int i=0;i<num_row;i++)
            {
                MYSQL_ROW row=mysql_fetch_row(res);
                Json::Value video;
                video["id"]=atoi(row[0]);
                video["name"]=row[1];
                video["info"]=row[2];
                video["video"]=row[3];
                video["image"]=row[4];
                videos->append(video);
                
                
            }
            _mutex.unlock();//解锁
            mysql_free_result(res);
            return true;
        }
        bool SelectOne(int video_id, Json::Value *video)       // 查询指定视频信
        {
            // _mutex.lock();//加锁
            // #define SELECTONE_VIDEO "select *from tb_video where id=%d;"
            // char sql[1024]={0};
            // sprintf(sql,SELECTONE_VIDEO,video_id);
            // bool ret=MysqlQuery(_mysql,sql);
            //  if(ret==false)
            // {
            //     _mutex.unlock();//解锁
            //     return false;
            // }
            // MYSQL_RES *res=mysql_store_result(_mysql);
            // if(res==NULL)
            // {
            //     _mutex.unlock();//解锁
            //     cout<<"mysql store result fauiled"<<endl;
            //     return false;
            // }
            // if(mysql_num_rows(res)!=1)
            // {
            //     cout<<"no have data"<<endl;
            //     _mutex.unlock();//解锁
            //     return false;
            // }
            // _mutex.unlock();//解锁
            // MYSQL_ROW row=mysql_fetch_row(res);
            //  (*video)["id"]=atoi(row[0]);
            //     (*video)["name"]=row[1];
            //     (*video)["info"]=row[2];
            //     (*video)["video"]=row[3];
            //     (*video)["image"]=row[4];
            // mysql_free_result(res);
            // return true;
            #define SELECTONE_VIDEO "select * from tb_video where id=%d;"
				char sql[1024] = {0};
				sprintf(sql, SELECTONE_VIDEO, video_id);
				_mutex.lock();//-----lock start 保护查询与保存结果到本地的过程
				bool ret = MysqlQuery(_mysql, sql);
				if (ret == false) {
					_mutex.unlock();
					return false;
				}
				MYSQL_RES *res = mysql_store_result(_mysql);
				if (res == NULL) {
					std::cout << "mysql store result failed!\n";
					_mutex.unlock();
					return false;
				}
				_mutex.unlock();//------lock end
				int num_rows = mysql_num_rows(res);
				if (num_rows != 1) {
					std::cout << "have no data!\n";
					mysql_free_result(res);
					return false;
				}
				MYSQL_ROW row = mysql_fetch_row(res);
				(*video)["id"] = video_id;
				(*video)["name"] = row[1];
				(*video)["info"] = row[2];
				(*video)["video"] = row[3];
				(*video)["image"] = row[4];
				mysql_free_result(res);
				return true;

        }
        bool selectLike(const string &key, Json::Value *videos) // 模糊查找视频
        {
             _mutex.lock();//加锁
            #define SELECTLIKE_VIDEO "select * from tb_video where name like '%%%s%%';"
            string sql;
            sql.resize(4090);
            sprintf(&sql[0],SELECTLIKE_VIDEO,key.c_str());
            bool ret=MysqlQuery(_mysql,sql);
             if(ret==false)
            {
                _mutex.unlock();//解锁
                return false;
            }
            MYSQL_RES *res=mysql_store_result(_mysql);
            if(res==NULL)
            {
                _mutex.unlock();//解锁
                cout<<"mysql store result fauiled"<<endl;
                return false;
            }
              int num_row=mysql_num_rows(res);
            for(int i=0;i<num_row;i++)
            {
                MYSQL_ROW row=mysql_fetch_row(res);
                Json::Value video;
                video["id"]=atoi(row[0]);
                video["name"]=row[1];
                video["info"]=row[2];
                video["video"]=row[3];
                video["image"]=row[4];
                videos->append(video);
            }
            _mutex.unlock();//解锁
            mysql_free_result(res);
            return true;
        }
    };
}
#endif
